package com.cory.module.oplog.core.wrapper;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import lombok.Data;
import com.cory.boot.utils.SpringUtils;
import com.cory.module.oplog.core.annotation.OpLogObject;
import com.cory.module.oplog.mapper.OplogMapper;
import com.cory.utils.bean.ReflectioUtils;
import com.cory.utils.lang.StringUtils;

@SuppressWarnings("rawtypes")
@Data
public class ClazzWrapper {
    private boolean withLogTag; // 是否有注解
    private OpLogObject logTag; // 属性注解
    
    private String objectAlias;
    private String objectName;
    private String objectId;
    private String objectData;
    
    private List<Field> fieldList;

    public ClazzWrapper(Class<?> clazz, Object object) {
        this.logTag = clazz.getAnnotation(OpLogObject.class);
        this.withLogTag = logTag != null;
        
        this.objectName = withLogTag ? logTag.name() : "";
        this.objectAlias = (withLogTag && logTag.alias().length() != 0) ? logTag.alias() : clazz.getSimpleName();
        
        if (this.withLogTag && object != null) {
            try {
                this.objectId = ReflectioUtils.getAccessibleField(object, logTag.id()).get(object).toString();
                
                String tableName = StringUtils.isNotBlank(logTag.table()) ? logTag.table() : StringUtils.toUnderScoreCase(this.objectAlias);
                
                this.objectData = SpringUtils.getBean(OplogMapper.class).getObjectData(tableName, logTag.id(), objectId, logTag.data());
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
        this.fieldList = getFields(clazz);
    }

    public List<Field> getFieldList() {
        return fieldList;
    }

    private List<Field> getFields(Class clazz) {
        List<Field> fieldList = new ArrayList<>();
        return getFields(fieldList, clazz);
    }

    private List<Field> getFields(List<Field> fieldList, Class clazz) {
        fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
        Class superClazz = clazz.getSuperclass();
        if (superClazz != null) {
            getFields(fieldList, superClazz);
        }
        return fieldList;
    }
}
